#include "DXUT.h" // this include has to be included in the beginning of each source file for compiling

#include "./../Headers/shader_texture.h"

namespace ShaderSpace {

	ShaderTexture::ShaderTexture() : texture(NULL), texture_formated(NULL), texture_gpu(NULL) {
		//if( ! CreatePointerAllocation( texture ) )
		//	throw Exception( "Couldn't allocate memmory!" );

		if( ! CreatePointerAllocation( texture_formated ) )
			throw Exception( "Couldn't allocate memmory!" );

		if( ! CreatePointerAllocation( texture_gpu ) )
			throw Exception( "Couldn't allocate memmory!" );

	};

	ShaderTexture::~ShaderTexture() {
		this->destroy();
		SafeDelete( texture );
		SafeDelete( texture_formated );
	};

	bool ShaderTexture::loadColorMatrix( const string &file_name ) {
		using namespace Visual::ColorSpace;
		FILE *parq = NULL;
		if( ! file_open( file_name, parq, "r" ) )
			return false;

		// TODO - proper readers - Rdb
		COLOR_POS temp;
		int w, h;
		if( fscanf_s( parq, "%d%d\n", &w, &h ) < 2 )
			return false;
		this->texture = new MAT_COLOR_POS( (usint) w, (usint) h );

		for( usint i = 0; i < texture->h; ++i ) {
			for( usint j = 0 ; j < texture->w; ++j ) {
				if( fscanf_s( parq, "%f%f%f\n", &temp.pos[R], &temp.pos[G], &temp.pos[B] ) < 3 )
					return false;
				this->texture->setVal(i,j,temp);
			}
		}

		return file_close(parq);
	};

	bool ShaderTexture::createOnDevice( ID3D11Device *target_device ){
		//ID3D11Texture2D *result_tex;
		D3D11_SUBRESOURCE_DATA tex_sub_initial_data;

		// the data used to initialize
		tex_sub_initial_data.pSysMem = texture->buf;
		// for 2D and 3D textures, number of bytes to skip when passing from one 1D level to the next one
		tex_sub_initial_data.SysMemPitch = texture->w*sizeof(COLOR_POS);
		// for 2D and 3D textures, number of bytes to skip when passing from one 2D level to the next one
		tex_sub_initial_data.SysMemSlicePitch = texture->h*tex_sub_initial_data.SysMemPitch; // Not needed since this is a 2D texture

		D3D11_TEXTURE2D_DESC tex_descr;

		tex_descr.Width = texture->w;
		tex_descr.Height = texture->h;
		tex_descr.MipLevels = 1;
		tex_descr.ArraySize = 1;

		tex_descr.SampleDesc.Count = 1;
		tex_descr.SampleDesc.Quality = 0;
		tex_descr.Usage = D3D11_USAGE_DYNAMIC;
		//tex_descr.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		tex_descr.Format = DXGI_FORMAT_R32G32B32_FLOAT;
		tex_descr.BindFlags = D3D11_BIND_SHADER_RESOURCE;

		tex_descr.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
		tex_descr.MiscFlags = 0;

		if( FAILED( target_device->CreateTexture2D( &tex_descr, &tex_sub_initial_data, NULL ) ) )
			throw Exception( "Wrong parameters!" ); // problem while allocating the buffer

		if( FAILED( target_device->CreateTexture2D( &tex_descr, &tex_sub_initial_data, texture_formated ) ) )
			return false;
		// mapped as texture!

		if( FAILED( target_device->CreateShaderResourceView( *texture_formated, NULL, NULL ) ) )
			return false;

		return target_device->CreateShaderResourceView( *texture_formated, NULL, texture_gpu ) != S_FALSE;
		//	MEMO - V_RETURN( D3DX11CreateShaderResourceViewFromFile( pd3dDevice, L"./../Resources/erro.bmp", NULL, NULL, &g_pTextureRV, NULL ) );
	};

	// TODO - work!
	bool ShaderTexture::saveToFile( ID3D11DeviceContext *target_device_context, const string &file_name ){
		//L"./Resources/LoadedTexture.bmp"
		return D3DX11SaveTextureToFile( target_device_context, *texture_formated, D3DX11_IMAGE_FILE_FORMAT::D3DX11_IFF_BMP, L"./Resources/erro.bmp" ) != S_FALSE;
	};

	// TODO - test and fix to use the given name
	bool ShaderTexture::loadFromFile( ID3D11Device *target_device, const string &file_name ){
		return D3DX11CreateShaderResourceViewFromFile( target_device, L"./Resources/erro.bmp", NULL, NULL, texture_gpu, NULL ) != S_FALSE;
	};

	bool ShaderTexture::destroy() {
		// TODO - when is it safe to call release?
		SAFE_RELEASE( *texture_formated );
		SAFE_RELEASE( *texture_gpu );
		return true;
	};

};
